package com.mask.example.controller;

import com.mask.token.annotation.RequireLogin;
import com.mask.token.common.Result;
import com.mask.token.model.MaskUserDetails;
import com.mask.token.service.MaskTokenLoginStrategy;
import com.mask.token.service.MaskTokenService;
import com.mask.token.util.MaskSecurityUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import java.util.List;

/**
 * 增强的认证控制器
 * 演示不同的登录策略
 *
 * @author mask
 * @since 1.0.0
 */
@Slf4j
@RestController
@ConditionalOnProperty(name = "example.enhanced-auth.enabled", havingValue = "true")
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class EnhancedAuthController {

    private final MaskTokenService tokenService;
    private final MaskTokenLoginStrategy loginStrategy;

    /**
     * 单点登录（账号互踢）
     */
    @PostMapping("/login/single")
    public Result<LoginResponse> singleSignOnLogin(@RequestBody LoginRequest request) {
        try {
            // 模拟用户验证
            MaskUserDetails userDetails = createUserDetails(request);
            
            // 使用单点登录策略
            String token = loginStrategy.handleLogin(userDetails, 
                    MaskTokenLoginStrategy.LoginStrategy.SINGLE_SIGN_ON);
            
            LoginResponse response = new LoginResponse();
            response.setToken(token);
            response.setStrategy("SINGLE_SIGN_ON");
            response.setMessage("单点登录成功，已踢出其他设备");
            
            return Result.success("登录成功", response);
        } catch (Exception e) {
            log.error("单点登录失败", e);
            return Result.fail(500, "登录失败: " + e.getMessage());
        }
    }

    /**
     * 多设备登录
     */
    @PostMapping("/login/multi")
    public Result<LoginResponse> multiDeviceLogin(@RequestBody LoginRequest request) {
        try {
            // 模拟用户验证
            MaskUserDetails userDetails = createUserDetails(request);
            
            // 使用多设备登录策略
            String token = loginStrategy.handleLogin(userDetails, 
                    MaskTokenLoginStrategy.LoginStrategy.MULTI_DEVICE);
            
            LoginResponse response = new LoginResponse();
            response.setToken(token);
            response.setStrategy("MULTI_DEVICE");
            response.setMessage("多设备登录成功");
            
            return Result.success("登录成功", response);
        } catch (Exception e) {
            log.error("多设备登录失败", e);
            return Result.fail(500, "登录失败: " + e.getMessage());
        }
    }

    /**
     * 同用户返回同一Token
     */
    @PostMapping("/login/reuse")
    public Result<LoginResponse> reuseTokenLogin(@RequestBody LoginRequest request) {
        try {
            // 模拟用户验证
            MaskUserDetails userDetails = createUserDetails(request);
            
            // 使用同用户返回同一Token策略
            String token = loginStrategy.handleLogin(userDetails, 
                    MaskTokenLoginStrategy.LoginStrategy.REUSE_TOKEN);
            
            LoginResponse response = new LoginResponse();
            response.setToken(token);
            response.setStrategy("REUSE_TOKEN");
            response.setMessage("同用户返回同一Token");
            
            return Result.success("登录成功", response);
        } catch (Exception e) {
            log.error("同用户返回同一Token登录失败", e);
            return Result.fail(500, "登录失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户登录统计
     */
    @GetMapping("/login/statistics")
    @RequireLogin
    public Result<MaskTokenLoginStrategy.LoginStatistics> getLoginStatistics() {
        try {
            Long userId = MaskSecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.fail(401, "用户未认证");
            }
            
            MaskTokenLoginStrategy.LoginStatistics statistics = 
                    loginStrategy.getUserLoginStatistics(userId);
            
            return Result.success("获取登录统计成功", statistics);
        } catch (Exception e) {
            log.error("获取登录统计失败", e);
            return Result.fail(500, "获取统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户所有Token
     */
    @GetMapping("/tokens")
    @RequireLogin
    public Result<List<com.mask.token.model.TokenInfo>> getUserTokens() {
        try {
            Long userId = MaskSecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.fail(401, "用户未认证");
            }
            
            List<com.mask.token.model.TokenInfo> tokens = tokenService.getUserAllTokens(userId);
            
            return Result.success("获取用户Token成功", tokens);
        } catch (Exception e) {
            log.error("获取用户Token失败", e);
            return Result.fail(500, "获取Token失败: " + e.getMessage());
        }
    }

    /**
     * 踢出指定设备
     */
    @PostMapping("/kick-device/{deviceId}")
    @RequireLogin
    public Result<Void> kickDevice(@PathVariable String deviceId) {
        try {
            Long userId = MaskSecurityUtil.getCurrentUserId();
            if (userId == null) {
                return Result.fail(401, "用户未认证");
            }
            
            // 查找并踢出指定设备的Token
            List<com.mask.token.model.TokenInfo> userTokens = tokenService.getUserAllTokens(userId);
            boolean kicked = false;
            
            for (com.mask.token.model.TokenInfo tokenInfo : userTokens) {
                if (deviceId.equals(tokenInfo.getDeviceId())) {
                    tokenService.logout(tokenInfo.getToken());
                    kicked = true;
                    log.info("踢出设备: {}, Token: {}", deviceId, tokenInfo.getToken());
                    break;
                }
            }
            
            if (kicked) {
                return Result.success("设备已踢出", null);
            } else {
                return Result.fail(404, "未找到指定设备");
            }
        } catch (Exception e) {
            log.error("踢出设备失败", e);
            return Result.fail(500, "踢出设备失败: " + e.getMessage());
        }
    }

    /**
     * 踢出所有其他设备（保留当前设备）
     */
    @PostMapping("/kick-others")
    @RequireLogin
    public Result<Void> kickOtherDevices() {
        try {
            Long userId = MaskSecurityUtil.getCurrentUserId();
            String currentDeviceId = MaskSecurityUtil.getCurrentUserDeviceId();
            
            if (userId == null) {
                return Result.fail(401, "用户未认证");
            }
            
            // 踢出除当前设备外的所有Token
            List<com.mask.token.model.TokenInfo> userTokens = tokenService.getUserAllTokens(userId);
            int kickedCount = 0;
            
            for (com.mask.token.model.TokenInfo tokenInfo : userTokens) {
                // 获取当前用户的Token进行比较
                String currentToken = MaskSecurityUtil.getCurrentUser() != null ? 
                        MaskSecurityUtil.getCurrentUser().getToken() : null;
                
                if (currentToken != null && !tokenInfo.getToken().equals(currentToken) &&
                    (currentDeviceId == null || !currentDeviceId.equals(tokenInfo.getDeviceId()))) {
                    tokenService.logout(tokenInfo.getToken());
                    kickedCount++;
                }
            }
            
            return Result.success("已踢出 " + kickedCount + " 个其他设备", null);
        } catch (Exception e) {
            log.error("踢出其他设备失败", e);
            return Result.fail(500, "踢出其他设备失败: " + e.getMessage());
        }
    }

    /**
     * 创建用户详情（模拟）
     */
    private MaskUserDetails createUserDetails(LoginRequest request) {
        MaskUserDetails userDetails = new MaskUserDetails();
        userDetails.setUserId(1L);
        userDetails.setUsername(request.getUsername());
        userDetails.setEmail("user@example.com");
        userDetails.setDeviceId(request.getDeviceId());
        userDetails.setUserAgent(request.getUserAgent());
        userDetails.setLoginIp("127.0.0.1");
        
        // 设置权限
        userDetails.addAuthority("ROLE_USER");
        userDetails.addAuthority("user:read");
        userDetails.addAuthority("user:write");
        
        return userDetails;
    }

    /**
     * 登录请求
     */
    @Data
    public static class LoginRequest {
        private String username;
        private String password;
        private String deviceId;
        private String userAgent;
    }

    /**
     * 登录响应
     */
    @Data
    public static class LoginResponse {
        private String token;
        private String strategy;
        private String message;
    }
}
